package acc_controllers

import (
	"chat-room/lib"
	"chat-room/providers"
	"chat-room/websocket/acc_service"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"net/http"
	"time"
)

type Websocket struct {
}

type responseFormat struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data string `json:"data"`
}

var (
	// 协议升级
	upGrader = websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool {
			providers.Logger.Info("升级协议", "ua:", r.Header["User-Agent"], "referer:", r.Header["Referer"])
			return true
		},
	}

	// 初始化
	clientManger = NewClientManager()
)

/**
 * @Author: yang
 * @Description：启动socket服务:服务监听
 * @Date: 2021/10/28 17:16
 */
func StartWebSocket() {
	serverIp := lib.GetServerIp()

	// @Todo 服務注冊--（IP推送的redis中）
	providers.Logger.Info("WebSocket 服务注册：", serverIp)

	// 创建master进程
	go clientManger.Start()

}

/**
 * @Author: yang
 * @Description：建立websocket连接
 * @Date: 2021/11/2 11:56
 */
func (ws *Websocket) Run(c *gin.Context) {
	// Token验证
	token := c.Param("token")
	userService := new(acc_service.UserService)
	if err := userService.CheckUserToken(token); err != nil {
		c.JSON(500, responseFormat{
			Code: 500,
			Msg:  "连接验证不通过",
		})
	}

	// 协议升级
	conn, err := upGrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		c.JSON(500, responseFormat{
			Code: 500,
			Msg:  "协议升级失败",
		})
	}

	// 创建Client
	currentTime := uint64(time.Now().Unix())
	client := NewClient(conn.RemoteAddr().String(), conn, currentTime, token)

	// 监听读写
	go client.ReadMsg()
	go client.WriteMsg()

	// 创建连接事件
	clientManger.Register <- client
}

/**
 * @Author: yang
 * @Description：信息广播
 * @Date: 2021/11/3 16:12
 */
func (ws *Websocket) Broadcast(c *gin.Context) {

	// 获取参数
	token := c.PostForm("token")
	msg := c.PostForm("message")

	if token == "" || msg == "" {
		c.JSON(500, responseFormat{
			Code: 500,
			Msg:  "参数有误",
		})
		return
	}

	// 消息入库
	logService := new(acc_service.LogService)
	err := logService.SaveLog(msg, token, 1)
	if err != nil {
	_:
		providers.Logger.Error("聊天记录入库失败", err)
	}

	// 信息序列化（json）
	sendJson := logService.ProductLog(msg, token, 2)

	// 推送本房间内所有人
	userService := new(acc_service.UserService)
	userTokenList := userService.GetUserTokenList(token)
	if userTokenList != nil {
		clientManger.Broadcast <- &BroadcastMsg{
			UserTokens: userTokenList,
			Msg:        []byte(sendJson),
		}
	}

	c.JSON(200, responseFormat{
		Code: 200,
		Msg:  "推送成功",
	})

	return
}
